home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
docp_1_1.zip
/
DOCP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-04
|
57KB
|
2,401 lines
/*
docp.c - Directory-Oriented CoPy
Fancy file copy program for MS-DOS
Copyright (c) 1992, Roy Bixler
Originally by: David Oertel
Atari ST port, overall cheez-whiz: Roy Bixler
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <conio.h>
#include <io.h>
#include <alloc.h>
#include <stdlib.h>
#include <string.h>
#include <sys\stat.h>
#include <dir.h>
#include <dos.h>
#include <fcntl.h>
#include <ctype.h>
#define DOT_NOTATION(dir) !strcmp(dir, "\.")
#include "docp.h"
#include "doc.h"
#include "elib.h"
#include "protypes.h"
#define OPT_LIST "abcdfghijlmnorstvwz?"
#define GET_OPT_LIST "AaBbCcD:d:F:f:GgHhIiJjLlMmNnOoRrSsTtVvW:w:Zz?"
#define DOT_NOTATION(dir) !strcmp(dir, "\.")
#define MAX_BUF 0xfffeU
extern int Optind;
extern char *optarg;
long Options = 0L;
char Cur_source_dir[FILENAME_MAX], Org_dest_dir[FILENAME_MAX];
ENTRY *Ptr;
void *Buf_ptr;
void *File_buf;
int Reading_flag; /* set if 'reading:' has been printed last
* reset if 'writing:' has been printed last */
/* modes of date compare via 'd' option */
#define D_BEFORE 1
#define D_ON 2
#define D_AFTER 4
DATE_NODE *Fdate; /* used to store date entered via 'd' option */
TIME_NODE *Ftime; /* used to store time entered via 'w' option */
FILE *From_file_ptr; /* file containing file list ('-f' option) */
int Retry = 0; /* set if target disk is full and user chooses to
* continue */
int Copied_a_file = 0; /* set if at least one file was copied */
ENTRY *Src_tab[HASH_TAB_SIZE]; /* contains source-file names */
ENTRY *Dst_tab[HASH_TAB_SIZE]; /* contains destination-file names */
typedef struct file_list {
char *string;
struct file_list *next;
} STDIN_TOKEN;
/* linked list globals containing file list from stdin */
STDIN_TOKEN *Stdin_list_head = NULL;
STDIN_TOKEN *Stdin_list_tail = NULL;
STDIN_TOKEN *Stdin_list_current = NULL;
void main(int argc, char *argv[])
{
char src_dir[MAXDIR];
char dst_dir[MAXDIR];
unsigned long buf_size;
int num_args;
char **argv_ptr;
char *all[2] = {"*.*", NULL};
get_flags(argv, argc);
check_flags();
check_and_format_dirs(argc, argv, src_dir, dst_dir);
#ifdef LATER
check_target_removeable(dst_dir);
#else
Options |= O_TARGET_REMOVEABLE; /* assume any disk is removeable */
#endif
File_buf = get_file_buf(&buf_size);
Buf_ptr = File_buf;
argv += Optind + 2;
num_args = argc - Optind - 2;
argv_ptr = argv;
if (Options & O_FROM_STDIN)
build_stdin_file_list(&num_args);
else if (Options & O_FROM_FILE) {
char buf[80];
num_args = 0;
while (fgets(buf, 79, From_file_ptr) != NULL)
num_args++;
rewind(From_file_ptr);
} else if (num_args == 0) {
num_args = 1;
argv_ptr = all;
}
strcpy(Org_dest_dir, dst_dir);
if (Options & O_CHECK)
fprintf(stdout, "The following files would be copied or moved:\n");
else if (Options & O_ZAPTARGET)
zap_target(dst_dir, 1);
copy_files(src_dir, dst_dir, argv_ptr,
num_args, File_buf, buf_size);
write_buffer(File_buf);
clear_archive_bits(src_dir);
if (!Copied_a_file)
fprintf(stdout, "no files copied\n");
farfree(File_buf);
}
/*
* check_and_format_dirs()
*
* Input:
* argc - command line argument count
* argv - command line arguments
* Optind - argument index from getopt()
* Output:
* src_dir - source directory name
* dst_dir - destination directory name
* Comments:
* The source and destination directories are formatted
* The source directory is checked for existence
* The destination directory is created if it doesn't exist
* The two directories are checked to insure that they are
* different
* The destination is checked to insure that it is not a
* subdirectory of the source
*/
void check_and_format_dirs(int argc, char *argv[],
char *src_dir, char *dst_dir)
{
if ((argc-Optind) < 2)
usage();
strcpy(src_dir, argv[Optind]);
check_if_dir_exists(src_dir, 0);
strcpy(dst_dir, argv[Optind + 1]);
check_if_dir_exists(dst_dir, 1);
format_dir(argv[Optind], '\1', src_dir);
format_dir(argv[Optind + 1], '\1', dst_dir);
check_if_dirs_compatible(src_dir, dst_dir);
}
#ifdef LATER
/*
* check_target_removeable()
*
* Input:
* dst_dir - destination directory name
* Output:
* Options - will be modified if target directory is removeable
* (i.e. a floppy disk)
*/
void check_target_removeable(char *dst_dir)
{
char dst_drive;
if (islower(dst_drive = dst_dir[0]))
dst_drive = toupper(dst_drive);
if ((dst_drive == 'A') || (dst_drive == 'B'))
Options |= O_TARGET_REMOVEABLE;
}
#endif
/*
* check_if_dirs_compatible()
*
* Input:
* src_dir - The formatted source directory name
* dst_dir - The formatted destination directory name
* Comments:
* terminates if:
* 1 - The two directories are the same
* 2 - The destination is a subdirectory of
* the source
*/
void check_if_dirs_compatible(char *src_dir, char *dst_dir)
{
if (Options & O_CHECK)
return;
if (!strcmp(src_dir, dst_dir)) {
fprintf(stderr,
"source and destination directories are the same\n");
exit(-1);
}
if ((Options & O_RECURSIVE) &&
!strncmp(src_dir, dst_dir, strlen(src_dir))) {
fprintf(stderr,
"destination directory is a subdirectory of the source directory \nwhile in recursive mode\n");
exit(-1);
}
}
/*
* check_if_dir_exists()
*
* Input:
* dir - the directory name
* is_dest - flag set if directory is a destination directory
* Comments:
* creates destination directory if it doesn't exist
* terminates if the source directory doesn't exist
*/
void check_if_dir_exists(char *dir, int is_dest)
{
int retval;
char *ext_path = append_dir_to_path(dir, "*.*");
struct ffblk tmp;
if ((!just_disk(dir)) && (findfirst(ext_path, &tmp, FA_DIREC)))
if ((is_dest) && ((Options & O_BATCH) ||
(printf("directory %s does not exist - ", dir),
ask_user("create it (Y/N/Q) ? "))))
create_dir(dir);
else {
printf("docp: directory '%s' does not exist\n", dir);
exit(-1);
}
free(ext_path);
}
/*
* create_dir()
*
* Input:
* dir - the directory to be created
* options - command line options
* Comments:
* creates destination directory
*/
void create_dir(char *dir)
{
char next_dir[MAXDIR], *p;
strcpy(next_dir, dir);
for (p=next_dir; *p; p++)
if (*p == '/')
*p = '\\';
p = next_dir;
while ((p = strchr(p, '\\')) != NULL) {
*p = '\0';
mkdir(next_dir);
*p++ = '\\';
}
if (mkdir(dir) == -1) {
fprintf(stderr, "cannot create directory '%s'\n", dir);
exit(-1);
}
else if (Options & O_VERBOSE)
printf("created directory '%s'\n", dir);
}
/*
* just_disk()
*
* Input:
* dir - the directory to be checked
* Output:
* returns :
* 1 - if 'dir' is a "just" a directory specification of the
* form 'X:', 'X:\' or 'X:/'
* 0 - otherwise
*/
int just_disk(char *dir)
{
if (dir == NULL)
return 0;
switch (strlen(dir)) {
case 1:
return ((dir[0] == '/') || (dir[0] == '\\'));
case 2:
return ((isalpha(dir[0])) && (dir[1] == ':'));
case 3:
return ((isalpha(dir[0])) && (dir[1] == ':') &&
((dir[2] == '/') || (dir[2] == '\\')));
default:
return 0;
}
}
/*
* change_disk()
*
* Input:
* dir - the destination directory
* curdir - the current working directo